package com.master.echoserver;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.List;
import com.master.echoserver.SelectorLoopType;;

public class EchoServer {
    public static SelectorLoop connectionAcceptor; //处理请求连接通道
    public static SelectorLoop connectionReader;  //处理IO读取
    Thread  readBellThread;
    /*设置一个连接队列,用于存放新的SOCKET连接通道，
     * connectionAcceptor响应请求并将请求通道放入队列
     * connectionReader 从队列中取出连接通道开始进行IO处理
    */
    public static List<SocketChannel> taskQueen = new ArrayList<SocketChannel>();
    //添加SelectionKey到队列
    public static void addTaskQueen(SocketChannel sc){
        synchronized (taskQueen) {
        	taskQueen.add(sc);
            //唤醒connectionReader线程
        	connectionReader.getSelector().wakeup();
        }
    }
    public static void main(String[] args) throws IOException {
        new EchoServer().startServer();
    }
     
    // 启动服务器
    public void startServer() throws IOException {
        // 准备好一个闹钟.当有链接进来的时候响.
        connectionAcceptor = new SelectorLoop(SelectorLoopType.ACCEPTOR);
         
        // 准备好一个闹钟,当有read事件进来的时候响.
        connectionReader = new SelectorLoop(SelectorLoopType.READER);
         
        // 开启一个server channel来监听
        ServerSocketChannel ssc = ServerSocketChannel.open();
        // 开启非阻塞模式
        ssc.configureBlocking(false);
         
        ServerSocket socket = ssc.socket();
        
        socket.bind(new InetSocketAddress("127.0.0.1",7878),100);
         
        // 给闹钟规定好要监听报告的事件,这个闹钟只监听新连接事件.
        ssc.register(connectionAcceptor.getSelector(), SelectionKey.OP_ACCEPT);
        new Thread(connectionAcceptor).start();

    }
}
     